package com.world.rickcloudendpoint.algorithm;

/**
 * @description: 点
 * @author: jlsong
 * @date: 2021/12/27 23:04:55
 * @version: 1.0
 */
public class Point {

    private double x;
    private double y;
    private double z;

    //构造函数
    public Point() {
        x = 0;
        y = 0;
        z = 0;
    }

    //构造函数
    public Point(double _x, double _y, double _z) {
        x = _x;
        y = _y;
        z = _z;
    }

    //计算2线段是否相交
    public static boolean IsSegmentsCross(Point a, Point b, Point c, Point d) {
        // 三角形abc 面积的2倍
        double area_abc = (a.x - c.x) * (b.z - c.z) - (a.z - c.z) * (b.x - c.x);

        // 三角形abd 面积的2倍
        double area_abd = (a.x - d.x) * (b.z - d.z) - (a.z - d.z) * (b.x - d.x);

        // 面积符号相同则两点在线段同侧,不相交
        if (area_abc * area_abd >= 0) {
            return false;
        }

        // 三角形cda 面积的2倍
        double area_cda = (c.x - a.x) * (d.z - a.z) - (c.z - a.z) * (d.x - a.x);
        // 三角形cdb 面积的2倍
        double area_cdb = area_cda + area_abc - area_abd;
        if (area_cda * area_cdb >= 0) {
            return false;
        }

        //计算交点坐标
        double t = area_cda / (area_abd - area_abc);
        double dx = t * (b.x - a.x),
                dy = t * (b.z - a.z);
        // x: a.x + dx
        //z: a.z + dy
        return true;
    }

    //从字符串获取Point类型
    public static Point FromString(String str, String splitStr) {
        Point ret = new Point(0, 0, 0);
        String[] sourceStrArray = str.split(splitStr);
        if (sourceStrArray.length == 3) {
            double x = Double.parseDouble(sourceStrArray[0]);
            double y = Double.parseDouble(sourceStrArray[1]);
            double z = Double.parseDouble(sourceStrArray[2]);

            ret.x = x;
            ret.y = y;
            ret.z = z;

        }
        return ret;
    }

    //获取X
    public double getX() {
        return x;
    }

    //设置X
    public void setX(double x) {
        this.x = x;
    }

    //获取Y
    public double getY() {
        return y;
    }

    //设置Y
    public void setY(double y) {
        this.y = y;
    }

    //获取Z
    public double getZ() {
        return z;
    }

    //设置z
    public void setZ(double z) {
        this.z = z;
    }

    //加
    public Point add(Point v) {
        Point ret = new Point();
        ret.x = x + v.x;
        ret.y = y + v.y;
        ret.z = z + v.z;
        return ret;
    }

    //减
    public Point sub(Point v) {
        Point ret = new Point();
        ret.x = x - v.x;
        ret.y = y - v.y;
        ret.z = z - v.z;
        return ret;
    }

    //乘
    public Point mul(Point v) {
        Point ret = new Point ();
        ret.x = x * v.x;
        ret.y = y * v.y;
        ret.z = z * v.z;
        return ret;
    }

    //乘
    public Point mul(double v) {
        Point ret = new Point ();
        ret.x = x * v;
        ret.y = y * v;
        ret.z = z * v;
        return ret;
    }

    //除
    public Point div(Point v) {
        Point ret = new Point ();
        ret.x = x / v.x;
        ret.y = y / v.y;
        ret.z = z / v.z;
        return ret;
    }

    //点积
    public double dot(Point v) {
        double ret = 0;
        ret = x * v.x + y * v.y + z * v.z;
        return ret;
    }

    //叉乘
    public Point cross(Point v) {
        Point ret = new Point ();
        ret.x = y * v.z - z * v.y;
        ret.y = z * v.x - x * v.z;
        ret.z = x * v.y - y * v.x;
        return ret;
    }

    //长度
    public double length() {
        return Math.sqrt(x * x + y * y + z * z);
    }

    //距离
    public double distance(Point v) {
        double x1 = x - v.x;
        double y1 = y - v.y;
        double z1 = z - v.z;
        return Math.sqrt(x1 * x1 + y1 * y1 + z1 * z1);
    }

    //归一化
    public Point normalize() {
        double len = length();
        return new Point (x / len, y / len, z / len);
    }

    @Override
    public String toString() {
        return "Point {" +
                "x=" + x +
                ", y=" + y +
                ", z=" + z +
                '}';
    }

}
